package com.example.ass7;

import java.io.File;
import java.io.IOException;
import java.util.List;

import biuoop.DialogManager;
import biuoop.KeyboardSensor;

import com.example.ass7.animation.AnimationRunner;
import com.example.ass7.animation.EndScreen;
import com.example.ass7.animation.HighScoresAnimation;
import com.example.ass7.animation.KeyPressStoppableAnimation;
import com.example.ass7.geometryprimitives.Counter;
import com.example.ass7.level.GameLevel;
import com.example.ass7.level.LevelInformation;

/**
 * @author Meirav Ben Izhak
 */
public class GameFlow {
    private final KeyboardSensor keyboardSensor;
    private final AnimationRunner animationRunner;
    private final Counter currentScore;
    private final Counter numberOfLives;
    private final HighScoresTable highScoresTable;

    /**
     * @param animationRunner
     *            animationRunner
     * @param keyboardSensor
     *            keyboardSensor
     * @param highScoresTable
     *            highScoresTable
     */
    public GameFlow(
        AnimationRunner animationRunner, KeyboardSensor keyboardSensor,
        HighScoresTable highScoresTable) {

        this.keyboardSensor = keyboardSensor;
        this.animationRunner = animationRunner;
        this.currentScore = new Counter();
        this.numberOfLives = new Counter();
        this.numberOfLives.increase(7);
        this.highScoresTable = highScoresTable;
    }

    /**
     * @param levels
     *            levels
     * @throws IOException
     *             IOException
     */
    public void runLevels(List<LevelInformation> levels) throws IOException {
        this.numberOfLives.increase(-this.numberOfLives.getValue());
        this.numberOfLives.increase(3);
        double alienSpeed = 50;
        double speedGap = 30;
        int levelNumber = 1;

        while (true) {
            for (LevelInformation levelInfo : levels) {

                GameLevel level = new GameLevel(levelInfo,
                        this.keyboardSensor, this.animationRunner,
                        this.currentScore, this.numberOfLives);

                level.initialize(alienSpeed, levelNumber);

                while (level.hasMoreAliens()
                        && !level.noMoreLives()
                        ) {
                    level.playOneTurn(alienSpeed);
                }

                alienSpeed += speedGap;
                levelNumber++;

                if (level.noMoreLives()) {
                    String name = this.showAskNameDialog();
                    this.saveHighScoresTable(name);
                    this.animationRunner.run(new KeyPressStoppableAnimation(
                            this.keyboardSensor, KeyboardSensor.SPACE_KEY,
                            new EndScreen(Boolean.FALSE, this.currentScore)));
                    this.animationRunner.run(new KeyPressStoppableAnimation(
                            this.keyboardSensor, KeyboardSensor.SPACE_KEY,
                            new HighScoresAnimation(this.highScoresTable)));
                    return;
                }
            }
        }
//        String name = this.showAskNameDialog();
//        this.saveHighScoresTable(name);
//        this.animationRunner.run(new KeyPressStoppableAnimation(
//                this.keyboardSensor, KeyboardSensor.SPACE_KEY, new EndScreen(
//                        Boolean.TRUE, this.currentScore)));
//        this.animationRunner.run(new KeyPressStoppableAnimation(
//                this.keyboardSensor, KeyboardSensor.SPACE_KEY,
//                new HighScoresAnimation(this.highScoresTable)));
    }

    /**
     * @return String
     */
    private String showAskNameDialog() {
        DialogManager dialog = this.animationRunner.getGUI().getDialogManager();
        String name = dialog.showQuestionDialog("Name", "What is your name?",
                "Anonymous");
        this.highScoresTable.add(new ScoreInfo(name, this.currentScore
                .getValue()));
        System.out.println("write record: name("
                + name + "), score(" + this.currentScore.getValue() + ")");
        return name;
    }

    /**
     * @param name
     *            name
     * @throws IOException
     *             IOException
     */
    private void saveHighScoresTable(String name) throws IOException {
        File file = new File(Ass7Game.FILE_NAME);
        this.highScoresTable.save(file);
    }
}
